<template>
  <el-card class="box-card">
    <el-dialog
      v-model="dialogVisible"
      destroy-on-close
      :title="isAdd ? '增加角色' : '角色授权'"
      width="25%"
    >
      <template v-if="isAdd">
        <el-form-item label="角色名称">
          <el-input autofocus v-model="rolename" />
        </el-form-item>
        <el-form-item label="权限菜单">
          <el-tree
            :default-checked-keys="dck"
            @check-change="cchange"
            ref="roletree"
            :data="allroutes"
            show-checkbox
            :check-strictly="isCheck"
            node-key="path"
            highlight-current
            default-expand-all
            :props="defaultProps"
          />
        </el-form-item>
      </template>
      <template v-else>
        <el-tree
          :default-checked-keys="dck"
          ref="roletree"
          :data="allroutes"
          :check-strictly="isCheck"
          show-checkbox
          node-key="path"
          highlight-current
          default-expand-all
          :props="defaultProps"
        />
      </template>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancel">取消</el-button>
          <el-button type="primary" @click="submit"> 确定 </el-button>
        </span>
      </template>
    </el-dialog>
    <template #header>
      <div class="card-header">
        <h3>角色管理</h3>
        <div class="buttons">
          <el-button type="primary" v-hasPermiss="'add'" :icon="Plus" @click="openModel"
            >增加角色</el-button
          >
          <el-button type="danger" v-hasPermiss="'alldelete'" @click="dels()" :icon="Delete"
            >批量删除</el-button
          >
          <el-button
            type="primary"
            v-hasPermiss="'refresh'"
            @click="refresh"
            color="green"
            :icon="RefreshRight"
            >刷新</el-button
          >
        </div>
      </div>
    </template>
    <el-scrollbar height="620px">
      <div class="table">
        <el-table
          height="600px"
          ref="fileTable"
          v-loading="tableLoading"
          element-loading-text="数据加载中..."
          :element-loading-spinner="svg"
          element-loading-svg-view-box="-10, -10, 50, 50"
          element-loading-background="rgba(122, 122, 122, 0)"
          :data="tableData"
          style="width: 100%"
          highlight-current-row
          @selection-change="handleSelectionChange"
          @row-click="rclick"
        >
          <el-table-column type="selection" align="center" />
          <el-table-column fixed align="center" :show-overflow-tooltip="true" prop="_id" label="ID">
            <template #default="scope">
              <span class="cp" @click.stop="copyText(scope.row._id)"> {{ scope.row._id }}</span>
            </template>
          </el-table-column>
          <el-table-column
            align="center"
            :show-overflow-tooltip="true"
            prop="rolename"
            label="角色"
          >
            <template #default="scope">
              <span v-if="!isedit" class="cp" @dblclick="modifyrolename(scope.row)">
                {{ scope.row.rolename }}</span
              >
              <el-input
                ref="ipt"
                v-else-if="isedit && smodifyrolename == scope.row.rolename"
                style="width: 100px"
                v-model="editInfo"
                @blur="namemodify"
              />
            </template>
          </el-table-column>
          <el-table-column
            align="center"
            :show-overflow-tooltip="true"
            prop="role"
            label="权限"
            width="660"
          >
            <template #default="scope">
              <span>
                {{ scope.row.role.length == 0 ? "暂无权限" : scope.row.role.join("  ") }}</span
              >
            </template>
          </el-table-column>
          <el-table-column align="center" prop="_id" fixed="right" label="操作" width="500">
            <template #default="scope">
              <el-button
                color="green"
                :disabled="!svalue.includes(scope.row._id)"
                :icon="Grid"
                v-hasPermiss="'distribute'"
                @click.stop="distribute(scope.row)"
              >
                分配权限
              </el-button>
              <el-button
                v-hasPermiss="'delete'"
                type="danger"
                :icon="Delete"
                @click.stop="delrole(scope.row._id)"
              >
                删除
              </el-button>
              <el-button
                v-hasPermiss="'modify'"
                type="primary"
                :icon="Edit"
                @click.stop="xg(scope.row)"
              >
                修改角色名
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-scrollbar>
  </el-card>
</template>

<script setup lang="ts">
import { getRoleList, addRole, delRole, distributeRole } from "@/api/role"
import { allroutes } from "../router/index"
import { Delete, Edit, RefreshRight, Grid, Plus } from "@element-plus/icons-vue"
import { ElTree } from "element-plus"
import type { TreeOptionProps } from "element-plus/es/components/tree/src/tree.type"
const { proxy } = getCurrentInstance() as any
const dialogVisible = ref(false)
const cid = ref("")
const dck = ref<any[]>([])
const isAdd = ref(false)
const rolename = ref("")
const cancel = () => {
  dialogVisible.value = false
}
const editInfo = ref("")
const ipt = ref<HTMLInputElement | undefined>()
const isedit = ref(false)
const smodifyrolename = ref("")
const sid = ref("")
const isCheck = ref(false)
const cchange = () => {
  isCheck.value = false
}
const xg = async (item: any) => {
  isedit.value = true
  sid.value = item._id
  smodifyrolename.value = item.rolename
  editInfo.value = item.rolename
  await nextTick()
  ipt.value?.focus()
}
const namemodify = () => {
  if (!editInfo.value) {
    isedit.value = false
    return ElMessage.error("角色不能为空")
  }
  const loading = ElLoading.service({
    lock: true,
    text: "Loading",
    background: "rgba(0, 0, 0, 0)",
  })
  distributeRole("/bem/role/distribute", {
    id: sid.value,
    rolename: editInfo.value,
  })
    .then((res) => {
      if (res.code == 200) {
        getlist("角色名修改成功")
        dialogVisible.value = false
      } else {
        editInfo.value = ""
        ElMessage.error(res.msg)
      }
    })
    .catch((err) => {
      ElMessage.error(JSON.stringify(err))
    })
    .finally(() => {
      loading.close()
      isedit.value = false
    })
}
const modifyrolename = async (item: any) => {
  isedit.value = true
  sid.value = item._id
  smodifyrolename.value = item.rolename
  editInfo.value = item.rolename
  await nextTick()
  ipt.value?.focus()
}
const delrole = (val: any) => {
  ElMessageBox.confirm("确定删除此角色?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      const loading = ElLoading.service({
        lock: true,
        text: "Loading",
        background: "rgba(0, 0, 0, 0)",
      })

      delRole("/bem/role/delrolename", {
        ids: Array.isArray(val) ? JSON.stringify([...val]) : JSON.stringify([val]),
      })
        .then((res: any) => {
          if (res.code == 200) {
            ElMessage.success(`成功删除${res.data.num}条角色数据`)
            getlist()
          } else {
            ElMessage.error(res.msg)
          }
        })
        .catch((err: any) => {
          ElMessage.error(JSON.stringify(err))
        })
        .finally(() => {
          loading.close()
        })
    })
    .catch(() => {})
}
const defaultProps = {
  children: "children",
  label(data: any) {
    return data.meta.name
  },
  disabled(data: any) {
    return data.path == "/home"
  },
} as unknown as TreeOptionProps
const roletree = ref<InstanceType<typeof ElTree>>()
const submit = () => {
  if (isAdd.value) {
    isCheck.value = false
    addrole()
  } else {
    isCheck.value = false
    modifyrole()
  }
}
const dels = () => {
  if (svalue.value.length == 0) {
    return ElMessage.error("未勾选要删除的数据")
  }
  delrole(svalue.value)
}
const rclick = (row: any) => {
  proxy.$refs.fileTable.toggleRowSelection(row)
}
const openModel = () => {
  dialogVisible.value = true
  isAdd.value = true
  dck.value = ["/home"]
}
const tableData = ref<any[]>([])
const copyText = (text: string) => {
  proxy.$Copy(text)
}
const modifyrole = () => {
  isCheck.value = false
  const loading = ElLoading.service({
    lock: true,
    text: "Loading",
    background: "rgba(0, 0, 0, 0)",
  })
  distributeRole("/bem/role/distribute", {
    id: cid.value,
    role: JSON.stringify([
      ...proxy.$refs.roletree.getHalfCheckedKeys(),
      ...proxy.$refs.roletree.getCheckedKeys(),
    ]),
  })
    .then((res) => {
      if (res.code == 200) {
        getlist("路由权限分配成功，重新登录后生效")
        dialogVisible.value = false
      } else {
        ElMessage.error(res.msg)
      }
    })
    .catch((err) => {
      ElMessage.error(JSON.stringify(err))
    })
    .finally(() => {
      loading.close()
    })
}
const distribute = async (item: any) => {
  isCheck.value = true
  setTimeout(() => {
    isCheck.value = false
  }, 100)
  dck.value = item.role
  cid.value = item._id
  isAdd.value = false
  dialogVisible.value = true
}
const addrole = () => {
  if (!rolename.value) return ElMessage.error("请输入添加角色名称")
  const loading = ElLoading.service({
    lock: true,
    text: "Loading",
    background: "rgba(0, 0, 0, 0)",
  })
  addRole("/bem/role/addrolename", {
    rolename: rolename.value,
    role: JSON.stringify([
      ...proxy.$refs.roletree.getHalfCheckedKeys(),
      ...proxy.$refs.roletree.getCheckedKeys(),
    ]),
  })
    .then((res) => {
      if (res.code == 200) {
        ElMessage.success("添加角色成功")
        getlist()
        dialogVisible.value = false
      } else {
        ElMessage.error(res.msg)
      }
    })
    .catch((err: any) => {
      ElMessage.error(JSON.stringify(err))
    })
    .finally(() => {
      loading.close()
      rolename.value = ""
    })
}
const refresh = () => {
  getlist("角色数据刷新成功")
}
const svalue = ref<any[]>([])
const svg = `
        <path class="path" d="
          M 30 15
          L 28 17
          M 25.61 25.61
          A 15 15, 0, 0, 1, 15 30
          A 15 15, 0, 1, 1, 27.99 7.5
          L 15 15
        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
      `
const tableLoading = ref(false)
const getlist = (desc?: string) => {
  getRoleList("/bem/role/getrolelist")
    .then((res) => {
      tableLoading.value = true
      if (res.code == 200) {
        tableData.value = res.data
      }
      if (desc) {
        ElMessage.success(desc)
      }
    })
    .catch((err: any) => {
      ElMessage.error(JSON.stringify(err))
    })
    .finally(() => {
      tableLoading.value = false
    })
}
const handleSelectionChange = (val: any) => {
  svalue.value = val.map((e: any) => e._id)
}
const init = async () => {
  getlist("获取列表成功")
}
init()
</script>

<style lang="scss" scoped>
:deep(.el-form-item__content) {
  margin: 10px auto;
}
.cp {
  cursor: pointer;
}
.box-card {
  width: calc(100% - 4px);
  // height: 800px;
  .table {
    width: 100%;
    padding: 10px;
    box-sizing: border-box;
  }
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    .buttons {
      display: flex;
      align-items: center;
    }
  }
}
</style>
